package com.allwees.bs.c.module.user.req;

import com.allwees.bs.c.module.app.AppDeviceInfo;
import com.allwees.bs.c.module.share.util.ShareEncryptor;
import com.allwees.bs.c.module.user.entity.UserEntity;
import com.allwees.bs.core.model.constant.EPromotionChannel;
import com.allwees.bs.core.model.share.bo.ShareBo;
import com.allwees.bs.core.model.user.constant.EUserSourceType;
import com.allwees.bs.core.modelbase.req.SignedReq;
import com.allwees.bs.core.modelbase.validate.ValidateItem;
import com.allwees.core.common.util.RandomUtil;
import com.allwees.core.common.util.http.RequestContext;
import com.allwees.core.common.util.json.JsonUtil;
import com.allwees.core.common.util.reflect.PojoUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * 注册Req
 *
 * @author yangylsky
 *
 */
@Data
@EqualsAndHashCode(callSuper = true)
@AllArgsConstructor
@NoArgsConstructor
public class RegisterReq extends SignedReq implements AppDeviceInfo {
	private String email;

	private String firstName;

	private String lastName;

	private String password;

	private String shareCode;

	private EUserSourceType sourceType;

	private EPromotionChannel inviteChannel;

	private String deviceSource;

	private String deviceId;

	private String deviceModel;

	private String systemVersion;

	private String market;

	private String bundleId;

	private String appName;

	private String appVersion;

	private Float longitude;

	private Float latitude;

	private String d;

	@Override
	public ValidateItem[] getValidateItems() {
		return ArrayUtils.addAll(super.getValidateItems(),
				new ValidateItem(StringUtils.isBlank(email), "email can not be empty"),
				new ValidateItem(StringUtils.isBlank(firstName), "first name can not be empty"),
				new ValidateItem(StringUtils.isBlank(lastName), "last name can not be empty"),
				new ValidateItem(StringUtils.isBlank(password), "password can not be empty"),
				new ValidateItem(sourceType == null, "sourceType can not be a null"),
				new ValidateItem(!validShareCode(), "share code verify failed"));
	}

	private boolean validShareCode() {
		if(StringUtils.isBlank(shareCode)) {
			return true;
		}
		if(StringUtils.isNotBlank(d)) {
			String json = ShareEncryptor.decrypt(d);
			ShareBo shareBo = JsonUtil.fromJson(json, ShareBo.class);
			return shareCode.equals(shareBo.getShareCode());
		}
		return false;
	}

	@Override
	protected boolean ignoreValidate() {
		return EUserSourceType.TESTCASE.equals(sourceType) || EUserSourceType.MOCK.equals(sourceType);
	}

	@Override
	protected String signSeparator() {
		return sourceType.isApp() ? "_APP_" : "_WEB_";
	}

	@Override
	protected Object[] signValues() {
		return new Object[] {email, firstName, lastName, shareCode == null ? "" : shareCode, sourceType.name(),
				deviceSource == null ? "" : deviceSource, deviceId == null ? "" : deviceId, getTime().getTime()};
	}

    public UserEntity toUserEntity(PasswordEncoder passwordEncoder) {
    	UserEntity user = PojoUtil.copy(new UserEntity(), this);
    	user.setInviterShareCode(getShareCode());
		user.setPassword(passwordEncoder.encode(getPassword()));
		user.setInviteChannel(getInviteChannel());
		RequestContext.RequestInfo requestInfo = RequestContext.getContext();
		String agent = requestInfo.getAgent();
		if (StringUtils.isNotBlank(agent)) {
			user.setAgent(agent);
		}
		return user;
    }

	public static RegisterReq build(String email, String firstName, String lastName, EUserSourceType sourceType, String shareCode, EPromotionChannel inviteChannel) {
		RegisterReq req = new RegisterReq();
		req.setEmail(email);
		req.setFirstName(firstName);
		req.setLastName(lastName);
		req.setPassword(RandomUtil.generateString(8));
		req.setSourceType(sourceType);
		req.setShareCode(shareCode);
		req.setInviteChannel(inviteChannel);
		return req;
	}
}
